using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace Spike.TestHarness
{
    public partial class AddUrlDialog : Form
    {
        public AddUrlDialog()
        {
            InitializeComponent();

            ContractBuilder.ContractGenerator.Instance.StepCompleted += new Spike.ContractBuilder.ContractGenerator.StepCompletedHandler(Instance_StepCompleted);
        }
        delegate void SetStepCompletedCallback(Spike.ContractBuilder.ContractGenerator.STEP step, string message);
        void Instance_StepCompleted(Spike.ContractBuilder.ContractGenerator.STEP step, string message)
        {
            if (this.txtStatus.InvokeRequired)
            {
                SetStepCompletedCallback d = new SetStepCompletedCallback(Instance_StepCompleted);
                this.Invoke(d, new object[] { step, message });
            }
            else
            {
                if(txtStatus.Text.Length==0)
                    txtStatus.Text = step.ToString();
                else
                    txtStatus.Text = txtStatus.Text + "\r\n" + step.ToString();

                if(message.Length>0)
                    txtStatus.Text = txtStatus.Text + ":\r\n\t" + message;
            }

        }

        private void txtName_Validating(object sender, CancelEventArgs e)
        {
            if (txtName.Text.Trim() == string.Empty)
                errorProvider1.SetError(txtName, "Please enter in a name to uniquely refer to the new service reference.");
        }

        private void txtURL_Validating(object sender, CancelEventArgs e)
        {
            if (txtURL.Text.Trim() == string.Empty)
                errorProvider1.SetError(txtURL, "Please enter in a valid service location with a WSDL endpoint.");
        }

        public string URL
        {
            get { return txtURL.Text; }
            set { txtURL.Text = value; }
        }

        public string ClientName
        {
            get { return txtName.Text; }
            set { txtName.Text = value; }
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (!this.Validate())
                return;

            if (btnAdd.Text == "Close")
            {
                this.DialogResult = DialogResult.OK;
                this.Close();
                return;
            }

            try
            {
                btnAdd.Enabled = btnCancel.Enabled = false;
                errorProvider1.Clear();

                AddUrl addUrl = new AddUrl(AddUrlAsThread);
                addUrl.BeginInvoke(txtName.Text, txtURL.Text, new AsyncCallback(Completed), null);                
            }
            catch(Exception ex)
            {
                errorProvider1.SetError(txtURL, "Note able to retrieve service metadata: " + ex.Message);
            }
        }

        delegate string AddUrl(string name, string url);        

        static string AddUrlAsThread(string name, string url)
        {
            string errorMessage = string.Empty;
            try
            {
                ContractBuilder.ContractGenerator.Instance.AddUrl(name, url);
            }
            catch (Exception ex)
            {
                errorMessage = ex.Message;
            }
            return errorMessage;
        }

        private void Completed(IAsyncResult result)
        {
            AsyncResult async = (AsyncResult)result;
            AddUrl addUrl = (AddUrl)async.AsyncDelegate;
            string errorMessage = addUrl.EndInvoke(result);
            SetCompleted(errorMessage);
        }

        delegate void SetCompletedCallback(string message);

        public void SetCompleted(string message)
        {
            if (this.txtURL.InvokeRequired)
            {
                SetCompletedCallback d = new SetCompletedCallback(SetCompleted);
                this.Invoke(d, new object[] { message });
            }
            else
            {
                btnAdd.Enabled = btnCancel.Enabled = true;

                if (message == string.Empty)
                {
                    btnAdd.Text = "Close";
                    btnAdd.Enabled = true;
                    btnCancel.Enabled = false;
                }
                else
                {
                    errorProvider1.SetError(txtURL, "Note able to retrieve service metadata: " + message);
                }
            }
        }
    }
}